<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="js/canvas-painter.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<style type="text/css">

canvas{
	background-color: rgba(0,0,0,0.1);
/*	display: block;
	position: absolute;
	left: 0px;
	top: 0px;*/
}

</style>

</head>
<body>

<canvas width="600" height="480"></canvas>
<script type="text/javascript">

var cvs = document.querySelector('canvas');

var ctx = cvs.getContext('2d');
ctx.beginPath();
ctx.moveTo(80, 80);
// ctx.lineTo(80, 82);
ctx.lineTo(200, 280);

ctx.moveTo(23, 220);
ctx.lineTo(413, 240);

// ctx.arc(300, 240, 100, 0, Math.PI * 2);

// ctx.arc(300, 240, 200, Math.PI / 180 * -60, Math.PI / 180 * 240);
// ctx.rect(5, 5, 50, 50);
// ctx.lineTo(300, 240);
// ctx.closePath();
ctx.lineWidth = 25;
ctx.strokeStyle = '#aaa';
ctx.stroke();
// ctx.fillStyle = '#ff0000';
// ctx.fill();

var data = ctx.getImageData(0, 0, cvs.width, cvs.height);

var ImageDataHelper = {
	getIndex: function(w, x, y){
		return (w * y + x) * 4;
	},
	each: function(ctx, fn, x, y, w, h){
		x = x || 0;
		y = y || 0;
		w = w || ctx.canvas.width;
		h = h || ctx.canvas.height;
		w = Math.min(w, ctx.canvas.width);
		h = Math.min(h, ctx.canvas.height);
		var img = ctx.getImageData(x, y, w, h);
		var len = img.data.length, i = 0;
			console.log(img)
		var color = [], idx;
		for(; i < len; i += 4){
			idx = i / 4;
			x = idx % img.width;
			y = (idx / img.width) >> 0;
			color[0] = img.data[i + 0];
			color[1] = img.data[i + 1];
			color[2] = img.data[i + 2];
			color[3] = img.data[i + 3];
			if(fn(i, x, y, color)){
				return;
			}
		}
	},
	eachData: function(data, fn){
		var len = data.length, i = 0, c = [];
		for(; i < len; i += 4){
			c[0] = data[i + 0];
			c[1] = data[i + 1];
			c[2] = data[i + 2];
			c[3] = data[i + 3];
			if(fn(i, c)){
				return;
			}
		}
	},
	eachBlock: function(ctx, fn, w, h){
		h = h || w;
		for(var j = 0; j < ctx.canvas.height; j += h){
			for(var i = 0; i < ctx.canvas.width; i += w){
				var img = ctx.getImageData(i, j, w, h);
				if(fn(img, i, j)){
					break;
				}
			}
		}
	},
	findBorder: function(imgData, colorHandle){
		var w = imgData.width, idx, color = [];
		var previous, result = [], hash, c, p, _p, k;

		var id_helper = {};
		var key_helper = {};

		previous = undefined;
		for(var y = 0; y < imgData.height; y++){
			c = 0;
			for(var x = 0; x < imgData.width; x++){
				idx = (x + y * w) * 4;
				color[0] = imgData.data[idx + 0];
				color[1] = imgData.data[idx + 1];
				color[2] = imgData.data[idx + 2];
				color[3] = imgData.data[idx + 3];
				hash = colorHandle(color, x, y, idx / 4);
				if(hash != previous){
					if(previous != undefined){
						p = { id: idx / 4, x: x, y: y };
						if(c % 2 === 1){
							p.x -= 1;
						}
						result.push(p);
						key_helper[p.x + '_' + p.y] = id_helper[p.id] = result.length - 1;
					}
				}
				previous = hash;
			}
		}
		previous = undefined;
		for(var x = 0; x < imgData.width; x++){
			c = 0;
			for(var y = 0; y < imgData.height; y++){
				idx = (x + y * w) * 4;
				color[0] = imgData.data[idx + 0];
				color[1] = imgData.data[idx + 1];
				color[2] = imgData.data[idx + 2];
				color[3] = imgData.data[idx + 3];
				hash = colorHandle(color, x, y, idx / 4);
				if(hash != previous){
					if(previous != undefined){
						p = { id: idx / 4, x: x, y: y };
						if(c % 2 === 1){
							p.x -= 1;
						}
						k = p.x + '_' + p.y;
						if(k in result){
							result[k].cr = 1;
						} else {
							result.push(p);
							key_helper[k] = id_helper[p.id] = result.length - 1;
						}
					}
				}
				previous = hash;
			}
		}

		result.getByPosition = function(x, y){
			return this.getByKey(x + '_' + y);
		};
		result.getIndexByKey = function(key){
			return key in key_helper ? key_helper[key] : -1;
		};
		result.getIndexId = function(id){
			return id in id_helper ? id_helper[id] : -1;
		};
		result.getByKey = function(key){
			return this[key_helper[key]];
		};
		result.getById = function(id){
			var idx = this.getIndexId(id);
			return idx > -1 ? this[idx] : null;
		};
		result.getIdByKey = function(key){
			var idx = this.getIndexByKey(key);
			return idx < 0 ? null : this[idx].id;
		};

		// result.setElement = function(idx, fn){
		// 	if(idx in result){
		// 		fn(result[idx]);
		// 	}
		// };


		return result;
	},
	/*
	1	2	3
	8	O	4
	7	6	5
	 */
	pointConnectType: function(O, P){
		if(O.x == P.x && O.y == P.y) return 0;
		else if(Math.abs(O.x - P.x) > 1 || Math.abs(O.y - P.y) > 1) return -1;
		if(O.x == P.x){
			return O.y > P.y ? 2 : 6;
		} else if(O.x > P.x) {
			return O.y > P.y ? 1 : O.y < P.y ? 7 : 8;
		} else {
			return O.y > P.y ? 3 : O.y < P.y ? 5 : 4;
		}
	},
	createConnectIndex: function(o){
		var r = [];
		//1
		r.push((o.x - 1) + '_' + (o.y - 1));
		//2
		r.push((o.x) + '_' + (o.y - 1));
		//3
		r.push((o.x + 1) + '_' + (o.y - 1));
		//4
		r.push((o.x + 1) + '_' + (o.y));
		//5
		r.push((o.x + 1) + '_' + (o.y + 1));
		//6
		r.push((o.x) + '_' + (o.y + 1));
		//7
		r.push((o.x - 1) + '_' + (o.y + 1));
		//8
		r.push((o.x - 1) + '_' + (o.y));
		return r;
	},
	findConnectedPoint: function(arr, o){
		return arr.filter(function(p){
			return ImageDataHelper.pointConnectType(o, p) > 0;
		});
	}
};

// console.log(ImageDataHelper.pointConnectType([1,1],[0,1]))

/* mosaic */
// var size = 20;
// var points = [];
// ImageDataHelper.eachBlock(ctx, function(img, x, y){
// 	ImageDataHelper.eachData(img.data, function(index, color){
// 		if(color[3] > 0){
// 			points.push([x, y]);
// 			return true;
// 		}
// 	});
// }, size);

// points.forEach(function(point){
// 	ctx.beginPath();
// 	ctx.rect(point[0], point[1], size, size);
// 	ctx.closePath();
// 	ctx.fillStyle = 'rgba(0,0,0,0.3)';
// 	ctx.fill();
// });

/* Find border */
var imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
var r = ImageDataHelper.findBorder(imgData, function(color){
	if(color[3] > 0) return 1;
	else return 0;
});


r.forEach(function(o, i){
	var neibours = [];
	var keys = ImageDataHelper.createConnectIndex(o);
	var b;
	keys.forEach(function(key, idx){
		b = r.getByKey(key);
		var i = r.getIndexByKey(key);
		if(i > -1){
			neibours.push({ id: r[i].id, type: idx + 1 });
		}
	});

	// neibours = neibours.filter(function(b, i, bb){
	// 	if(!(b.type % 2)){
	// 		if(bb.find(function(bbb){
	// 			return Math.abs(bbb.type - b.type) == 1;
	// 		})){
	// 			return false;
	// 		}
	// 	}
	// 	return true;
	// })

	if(neibours.length > 0) {
		o.neibours = neibours;
		o.branch = neibours.map(function(a){ return a.type; });
	}
});

console.log(r);
r.forEach(function(a, i){
	// setTimeout(function(){
		ctx.beginPath();
		ctx.rect(a.x, a.y, 1, 1);
		ctx.closePath();
		ctx.fillStyle = 'rgba(0,0,0,1)';
		ctx.fill();	
	// }, 120 * i)
});

var ratios = r.filter(function(p){
	return p.branch &&
		p.branch.indexOf(4) > -1 &&
		p.branch.indexOf(5) > -1
		;
});

console.log(ratios)

// var bb = r.filter(function(p){
// 	return p.neibours.length > 2;
// });
// console.log(bb[0].neibours.filter(function(b, i, bb){
// 	if(!(b.type % 2)){
// 		if(bb.find(function(bbb){
// 			return Math.abs(bbb.type - b.type) == 1;
// 		})){
// 			return false;
// 		}
// 	}
// 	return true;
// }))

// function goPath(p, fn, log){

// 	if(!log) log = [];

// 	if(log.indexOf(p.id) > -1) return;
// 	log.push(p.id);

// 	fn(p);

// 	p.neibours.forEach(function(br){

// 		if(log.indexOf(br.id) > -1) return;

// 		var pt = r.getById(br.id);

// 		setTimeout(function(){
// 			goPath(pt, fn, log);

// 		}, 10)

// 		// if(log.indexOf(id) < 0){
// 			// goPath(r.getById(id), fn, log);
// 		// }
// 	});
// }

// function goForwardPath(p, fn, log){

// 	if(!log) log = [];

// 	if(log.indexOf(p.id) > -1) return;
// 	log.push(p.id);

// 	fn(p);
// 	var pt = r.getById(p.neibours[0].id);
// 	setTimeout(function(){
// 		goForwardPath(pt, fn, log);

// 	}, 10)
// }

// goPath(r[0], function(p){
// 	ctx.beginPath();
// 	ctx.rect(p.x, p.y, 1, 1);
// 	ctx.closePath();
// 	ctx.fillStyle = 'rgba(0,0,0,1)';
// 	ctx.fill();	
// })

// var p = r[0];
// var p1 = r.getById(p.branch[0].id);
// var p2 = r.getById(p.branch[1].id);
// console.log(p, p1, p2)
// ctx.rect(p.x, p.y, 1, 1);
// ctx.rect(p1.x, p1.y, 1, 1);
// ctx.rect(p2.x, p2.y, 1, 1);
// ctx.fillStyle = '#f00';
// ctx.fill();	

// var id = p.id;
// var c = 100;
// console.log(p)
// do{
// 	ctx.beginPath();
// 	ctx.rect(p.x - 1, p.y - 1, 2, 2);
// 	ctx.closePath();
// 	ctx.fillStyle = 'rgba(0,0,0,1)';
// 	ctx.fill();
// } while(--c > 0)

// console.log(path)

// var o = r[0];

// var conn = ImageDataHelper.findConnectedPoint(r, o);
// console.log(o, conn)

// // r.sort(function(a, b){
// // 	return (a[0] + a[1]) - (b[1] + b[0])
// // 	// return (a[0] * a[0] + a[1] * a[1]) - (b[0] * b[0] + b[1] * b[1]);
// // });

// // var first = r[0];
// // ctx.beginPath();
// // ctx.arc(first[0], first[1], 10, 0, Math.PI * 2);
// // ctx.closePath();
// // ctx.fillStyle = 'rgba(0,0,0,0.5)';
// // ctx.fill();	



// // console.log(r)

// var A1 = Math.PI / 180;
// var points = [[300, 30], [30, 30], [30, 300]];
// // points.forEach(function(a){
// // 	ctx.beginPath();
// // 	ctx.rect(a[0], a[1], 8, 8);
// // 	ctx.closePath();
// // 	ctx.fillStyle = '#f00';
// // 	ctx.fill();	
// // })

// function GetAngle(A, O, B){
// 	var ang1 = Math.atan2(A[1] - O[1], A[0] - O[0]);
// 	var ang2 = Math.atan2(B[1] - O[1], B[0] - O[0]);
// 	return ang2 - ang1;
// }
// console.log(GetAngle.apply(null, points) / A1)


</script>

</body>
</html>